<template>
  <basic-container>
    <div class="mar-b-15">
      <el-button :disabled="code === ''" size="small" type="primary" icon="el-icon-caret-right" @click="excuteSQL">执行</el-button>
      <el-button size="small" icon="el-icon-circle-close" @click="clearCode">清空</el-button>
      <el-button size="small" @click="sqlFormatter(null)">格式化</el-button>
    </div>
    <rs-codemirror v-model="code" mode="text/x-mysql"></rs-codemirror>
    <el-tabs class="mar-t-15" v-model="activeName" @tab-click="tabsChange">
      <el-tab-pane label="目录" name="treeview">
        <div>
          数据源 
          <el-select size="small" v-model="catalog.model" @change="catalogChange" placeholder="请选择">
            <el-option
              v-for="item in catalog.data"
              :key="item.Catalog"
              :label="item.Catalog"
              :value="item.Catalog">
            </el-option>
          </el-select>
        </div>
        <el-row class="mar-t-15" :gutter="15">
          <el-col :span="6">
            <div>
              <el-table
                v-if="catalog.model"
                v-loading="schema.loading"
                :data="schema.data.filter(data => !schemaSearch || data.Schema.includes(schemaSearch))"
                style="width: 100%"max-height="400" border>
                <el-table-column
                  v-for="(item , index) of schema.headers"
                  :prop="item.prop"
                  :label="item.label">
                  <template slot="header" slot-scope="scope">
                    <div>
                      {{scope.column.label}}
                      <el-badge v-if="scope.$index === 0" :value="schema.data.length" style="top: 5px;margin-left: 5px"></el-badge>
                      <div class="pull-right w-140">
                        <el-input v-model="schemaSearch" clearable size="mini" placeholder="输入关键字搜索"/>
                      </div>
                    </div>
                  </template>
                  <template slot-scope="scope">
                    <span @click="schema.model = scope.row[scope.column.property];schemaChange()" v-if="index === 0" class="cur-p" :class="{'text-primary': scope.row[scope.column.property] === schema.model}">{{ scope.row[scope.column.property] }}</span>
                    <span v-if="index > 0">{{ scope.row[scope.column.property] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-col>
          <el-col :span="6">
            <div>
              <el-table
                v-if="schema.model"
                v-loading="table.loading"
                :data="table.data.filter(data => !tableSearch || data.table_name.includes(tableSearch))"
                style="width: 100%"max-height="400" border>
                <el-table-column
                  v-for="(item , index) of table.headers"
                  :prop="item.prop"
                  :label="item.label">
                  <template slot="header" slot-scope="scope">
                    <div>
                      {{scope.column.label}}
                      <el-badge v-if="scope.$index === 0" :value="table.data.length" style="top: 5px;margin-left: 5px"></el-badge>
                      <div class="pull-right w-140">
                        <el-input v-model="tableSearch" clearable size="mini" placeholder="输入关键字搜索"/>
                      </div>
                    </div>
                  </template>
                  <template slot-scope="scope">
                    <span @click="table.model = scope.row[scope.column.property];tableChange()" v-if="index === 0" class="cur-p" :class="{'text-primary': scope.row[scope.column.property] === table.model}">{{ scope.row[scope.column.property] }}</span>
                    <span v-if="index > 0">{{ scope.row[scope.column.property] }}</span>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-col>
          <el-col :span="12">
            <div>
              <el-table
                v-if="table.model"
                v-loading="tableDescribe.loading"
                :data="tableDescribe.data"
                style="width: 100%"max-height="400" border>
                <el-table-column
                  v-for="(item , index) of tableDescribe.headers"
                  :prop="item.prop"
                  :label="item.label">
                  <template slot="header" slot-scope="scope">
                    <div>
                      {{scope.column.label}}
                      <el-badge v-if="scope.$index === 0" :value="tableDescribe.data.length" style="top: 5px;margin-left: 5px"></el-badge>
                    </div>
                  </template>
                </el-table-column>
              </el-table>
            </div>
          </el-col>
        </el-row>
        <div class="text-center" v-if="table.model && table.data.length">
          <el-select size="small" v-model="shortcutSql.model" placeholder="请选择">
            <el-option
              v-for="item in shortcutSql.list"
              :key="item.id"
              :label="item.label"
              :value="item.id">
            </el-option>
          </el-select>
          <el-checkbox class="mar-l-15" v-if="shortcutSql.model === 1" v-model="expandColumn">展开列</el-checkbox>
          <el-button class="mar-l-15" size="small" @click="createSql">生成SQL</el-button>
          <el-button class="mar-l-15" size="small" icon="el-icon-caret-right" type="primary" @click="createSql();excuteSQL()">执行</el-button>
        </div>
      </el-tab-pane>
      <el-tab-pane label="执行历史" name="history">
        <div class="text-right">
          <el-button @click="queryHistory" size="small" circle icon="el-icon-refresh"></el-button>
        </div>
        <div class="mar-t-15">
          <el-table
            v-loading="history.loading"
            :data="history.data"
            style="width: 100%" max-height="500" border>
            <el-table-column
              v-for="(item , index) of history.headers"
              :prop="item.prop"
              :label="item.label"
              :width="item.width || 'auto'"
              >
              <template slot-scope="{row , column , $index}">
                <div>
                  <!-- <template v-if="column.property === 'queryId'">
                    <span :class="{'cur-p': row.existdb , 'text-primary': row.existdb}">{{column.queryId}}</span>
                  </template> -->
                  <el-tag v-if="column.property === 'state'" size="small" effect="dark" :type="isRunning(row.state) ? '' : (result.types[row.state.toLocaleLowerCase()] || 'info')">
                    <i class="el-icon-loading" v-if="isRunning(row.state)"></i>
                    {{row.state}}
                  </el-tag>
                  <span v-else-if="column.property === 'createTime'">{{row['createTime'] | formatDate}}</span>
                  <el-popover
                    v-else-if="column.property === 'query'"
                    placement="top"
                    width="400"
                    v-model="row._popover"
                    trigger="manual"
                  >
                    <rs-codemirror style="max-height: 150px" v-if="row._popover"  mode="text/x-mysql" :value="sqlFormatter(row.query)" :readOnly="true"></rs-codemirror>
                    <span slot="reference" class="cur-p text-primary" @click="setRowPopover(row);">查看SQL</span>
                  </el-popover>
                  <span v-else-if="column.property === 'queryId'" :class="{'cur-p': row.existdb , 'text-primary': row.existdb}" @click="showExcuteResult(row , row.existdb)">{{row.queryId}}</span>
                  <span v-else>{{row[column.property]}}</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column width="160" align="center" label="操作">
              <template slot-scope="scope">
                <el-button v-if="isRunning(scope.row.state)" icon="el-icon-circle-close" @click="killQuery(scope.row.queryId)" size="small" type="text">Kill</el-button>
                <el-button size="small" icon="el-icon-document" type="text" @click="showLog(scope.row)">日志</el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>
      <el-tab-pane label="执行结果" name="result">
        <div>
          <div class="pad-tb-15">
            <span class="mar-r-5">ID：{{excuteQueryId}}</span>
            <el-tag size="mini" class="mar-r-50" effect="dark" :type="result.loading ? '' : (result.types[result.type] || 'info')">
              <i class="el-icon-loading" v-if="result.loading"></i>
              {{result.loading ? '加载中...' : result.type}}
            </el-tag>
            <template v-if="result.headers.length">
              <span class="mar-r-50">执行时间：{{result.createTime | formatDate}}</span>
              <span class="mar-r-50">执行时长：{{result.elapsedTime}}</span>
              <span class="mar-r-50">{{result.rawDataSize}}，{{result.count}}条记录</span>
            </template>
          </div>
          <el-alert
            v-if="result.error"
            :title="result.error"
            type="error">
          </el-alert>
          <el-table
            v-if="!result.error"
            v-loading="result.loading"
            :data="result.data"
            style="width: 100%" max-height="500" border>
            <el-table-column v-if="result.headers.length" label="行号" type="index" width="50"></el-table-column>
            <el-table-column
              v-for="(item , index) of result.headers"
              :prop="item.prop"
              :label="item.label">
            </el-table-column>
          </el-table>
        </div>
      </el-tab-pane>
    </el-tabs>
    <el-drawer
      title="日志"
      size="70%"
      :visible.sync="drawer"
      append-to-body
    >
      <div class="pad-lr-15" v-if="log.loading">
        <el-skeleton :rows="6" animated ></el-skeleton>
      </div>
      <div class="pad-lr-15" v-if="!log.loading">
        <el-row :gutter="15">
          <el-col :span="12">
            查询ID {{log.queryId}}
          </el-col>
          <el-col :span="12">
            状态 
            <el-tag size="small" effect="dark" :type="isRunning(log.state) ? '' : (result.types[log.state.toLocaleLowerCase()] || 'info')">
              <i class="el-icon-loading" v-if="isRunning(log.state)"></i>
              {{log.stateTitle}}
            </el-tag>
          </el-col>
        </el-row>
        <el-row :gutter="15">
          <el-col :span="12">
            <div><el-divider direction="vertical"></el-divider> 会话</div>
            <el-card class="mar-t-15 mar-l-15" shadow="never">
              <rs-label-row labelWidth="85">
                <rs-label-item label="用户">{{log.session.user}}</rs-label-item>
                <rs-label-item label="来源">{{log.session.source}}</rs-label-item>
                <rs-label-item label="数据源">{{log.session.catalog}}</rs-label-item>
                <rs-label-item label="地址">{{log.session.remoteUserAddress}}</rs-label-item>
                <rs-label-item label="资源估算">{{log.session.resourceEstimate}}</rs-label-item>
              </rs-label-row>
            </el-card>
          </el-col>
          <el-col :span="12">
            <div><el-divider direction="vertical"></el-divider> 执行情况</div>
            <div>
            <el-card class="mar-t-15 mar-l-15" shadow="never">
              <rs-label-row labelWidth="85">
                <rs-label-item label="提交时间">{{log.queryStats.createTime | formatDate}}</rs-label-item>
                <rs-label-item label="完成时间">{{log.queryStats.endTime | formatDate}}</rs-label-item>
                <rs-label-item label="已用时间">{{log.queryStats.elapsedTime}}</rs-label-item>
                <rs-label-item label="排队时间">{{log.queryStats.queuedTime}}</rs-label-item>
                <rs-label-item label="执行时间">{{log.queryStats.executionTime}}</rs-label-item>
              </rs-label-row>
            </el-card>
            </div>
          </el-col>
        </el-row>
        <el-row :gutter="15">
          <el-col :span="24">
            <div><el-divider direction="vertical"></el-divider> 资源利用情况</div>
            <el-card class="mar-t-15 mar-l-15" shadow="never">
              <el-row :gutter="15">
                <el-col :span="12">
                  <rs-label-row labelWidth="85">
                    <rs-label-item label="CPU时间">{{log.queryStats.totalCpuTime}}</rs-label-item>
                    <rs-label-item label="计划时间">{{log.queryStats.totalScheduledTime}}</rs-label-item>
                    <rs-label-item label="阻塞时间">{{log.queryStats.totalBlockedTime}}</rs-label-item>
                    <rs-label-item label="输入行">{{log.queryStats.processedInputPositions}}</rs-label-item>
                    <rs-label-item label="输入数据">{{log.queryStats.processedInputDataSize}}</rs-label-item>
                    <rs-label-item label="原始输入行">{{log.queryStats.rawInputPositions}}</rs-label-item>
                    <rs-label-item label="原始输入数据">{{log.queryStats.rawInputDataSize}}</rs-label-item>
                    <rs-label-item label="用户内存峰值">{{log.queryStats.peakTaskUserMemory}}</rs-label-item>
                  </rs-label-row>
                </el-col>
                <el-col :span="12">
                  <rs-label-row class="mar-l-30" labelWidth="85">
                    <!-- <rs-label-item label="CPU时间">{{log.queryStats.totalCpuTime}}</rs-label-item>
                    <rs-label-item label="计划时间">{{log.queryStats.totalScheduledTime}}</rs-label-item>
                    <rs-label-item label="阻塞时间">{{log.queryStats.totalBlockedTime}}</rs-label-item>
                    <rs-label-item label="输入行">{{log.queryStats.processedInputPositions}}</rs-label-item>
                    <rs-label-item label="输入数据">{{log.queryStats.processedInputDataSize}}</rs-label-item>
                    <rs-label-item label="原始输入行">{{log.queryStats.rawInputPositions}}</rs-label-item>
                    <rs-label-item label="原始输入数据">{{log.queryStats.rawInputDataSize}}</rs-label-item>
                    <rs-label-item label="用户内存峰值">{{log.queryStats.peakTaskUserMemory}}</rs-label-item> -->
                    <rs-label-item label="峰值总内存">{{log.queryStats.peakTotalMemoryReservation}}</rs-label-item>
                    <rs-label-item label="内存池">{{log.memoryPool}}</rs-label-item>
                    <rs-label-item label="累计用户内存">{{log.queryStats.cumulativeUserMemory}}</rs-label-item>
                    <rs-label-item label="输出行">{{log.queryStats.outputPositions}}</rs-label-item>
                    <rs-label-item label="输出数据">{{log.queryStats.outputDataSize}}</rs-label-item>
                    <rs-label-item label="写入输出行">{{log.queryStats.writtenOutputPositions}}</rs-label-item>
                    <rs-label-item label="写入输出逻辑数据大小">{{log.queryStats.writtenOutputLogicalDataSize}}</rs-label-item>
                    <rs-label-item label="写入输出物理数据大小">{{log.queryStats.writtenOutputPhysicalDataSize}}</rs-label-item>
                  </rs-label-row>
                </el-col>
              </el-row>
            </el-card>
          </el-col>
          <!-- <el-col :span="12">
            <div><el-divider direction="vertical"></el-divider> 时间线</div>
            <el-card class="mar-t-15 mar-l-15" shadow="never">
              <rs-label-row labelWidth="85">
                <rs-label-item label="并行性">{{log.queryStats.createTime | formatDate}}</rs-label-item>
                <rs-label-item label="预定时间/s">{{log.queryStats.endTime | formatDate}}</rs-label-item>
                <rs-label-item label="输入行数/s">{{log.queryStats.elapsedTime}}</rs-label-item>
                <rs-label-item label="输入字节/s">{{log.queryStats.queuedTime}}</rs-label-item>
                <rs-label-item label="内存利用率">{{log.queryStats.executionTime}}</rs-label-item>
              </rs-label-row>
            </el-card>
          </el-col> -->
        </el-row>
        <el-row>
          <el-col :span="24">
            <div><el-divider direction="vertical"></el-divider> 查询语句</div>
            <div class="mar-t-15 mar-l-15">
              <rs-codemirror :value="log.query" :readOnly="true" mode="text/x-mysql"></rs-codemirror>
            </div>
          </el-col>
        </el-row>
        <el-row v-if="log.isError">
          <el-col :span="24">
            <div><el-divider direction="vertical"></el-divider> 错误信息</div>
            <div class="mar-t-15 mar-l-15">
              <rs-label-row labelWidth="85">
                <rs-label-item label="错误类型">{{log.errorInfo.type}}</rs-label-item>
                <rs-label-item label="错误码">{{log.errorInfo.code}}</rs-label-item>
                <rs-label-item label="堆栈跟踪">
                  <pre>{{getLogErrorStack()}}</pre>
                </rs-label-item>
              </rs-label-row>
            </div>
          </el-col>
        </el-row>
      </div>
    </el-drawer>
  </basic-container>
</template>
<script>
import { format } from 'sql-formatter';
import {mapGetters} from "vuex";
import service from '@/api/arithmetic/interactive/index';
import website from '@/config/website'

export default {
  data(){
    return {
      code: '',
      datasource: null,
      expandColumn: false,
      catalog: {
        model: '',
        data: [],
        loading: false
      },
      schemaSearch: '',
      tableSearch: '',
      excuteQueryId: '',
      drawer: false,
      schema: {
        model: '',
        data: [],
        loading: false,
        headers: [
          {label: '库' , prop: 'Schema'}
        ]
      },
      table: {
        model: '',
        data: [],
        loading: false,
        headers: [
          {label: '表' , prop: 'table_name'}
        ]
      },
      tableDescribe: {
        model: '',
        data: [],
        loading: false,
        headers: [
          {label: '字段' , prop: 'Column'},
          {label: '字段类型' , prop: 'Type'},
          {label: '扩展信息' , prop: 'Extra'},
          {label: '备注' , prop: 'Comment'}
        ]
      },
      result: {
        data: [],
        headers: [],
        loading: false,
        type: '',
        createTime: '',
        elapsedTime: '',
        rawDataSize: '',
        count: 0,
        types: {
          'finished': 'success',
          'running': '',
          'failed': 'danger'
        },
        error: ''
      },
      history: {
        data: [],
        headers: [
          {label: '状态' , prop: 'state' , width: 120},
          {label: '查询ID' , prop: 'queryId' , width: 230},
          {label: '执行时长' , prop: 'elapsedTime', width: 100},
          {label: 'SQL' , prop: 'query'},
          {label: '执行时间' , prop: 'createTime' , width: 150},
          {label: '执行人' , prop: 'user', width: 100}
        ],
        loading: false
      },
      activeName: 'treeview',
      shortcutSql: {
        list: [
          {
            label: 'SELECT * FROM ... LIMIT 100',
            id: 1
          },
          {
            label: 'SHOW CREATE TABLE ...',
            id: 2
          },
          {
            label: 'DESCRIBE ...',
            id: 3
          },
          {
            label: 'SHOW STATS ...',
            id: 4
          }
        ],
        model: 1
      },
      log: {
        isError: false,
        loading: false,
        queryId: '',
        state: '',
        query: '',
        stateTitle: '',
        session: {
          resourceEstimate: ''
        },
        memoryPool: '',
        queryStats: {

        },
        errorInfo: {
          type: '',
          code: '',
          stack: [],
          errorType: '',
          message: ''
        }
      }
    }
  },
  mounted(){
    service.getDatasourceAuth().then(
      res => {
        console.log(res.data.datasources);
        if(res.data && res.data.datasources && res.data.datasources.length){
          Object.keys(res.data.datasources[0]).forEach(
            item => {
              this.datasource = {
                name: item,
                config: res.data.datasources[0][item]
              }
            }
          )
        }
        if(this.datasource.name){
          this.showCatalogs();
        }
      }
    )
  },
  computed: {
    ...mapGetters([
      "userInfo"
    ])
  },
  methods: {
    setRowPopover(row){
      this.history.data.forEach(
        item => {
          if(item.queryId !== row.queryId){
            item._popover = false;
          }
        }
      )
      row._popover = !row._popover;
    },
    getLogErrorStack(){
      let stack = [
        `${this.log.errorInfo.errorType}: ${this.log.errorInfo.message}`
      ].concat(this.log.errorInfo.stack);
      return stack.join('\nat ');
    },
    showLog(row){
      this.drawer = true;
      console.log(row);
      let log = {
        isError: false,
        state: '',
        stateTitle: '',
        memoryPool: '',
        query: '',
        session: {
          resourceEstimate: ''
        },
        queryStats: {},
        errorInfo: {
          type: '',
          code: '',
          stack: [],
          errorType: '',
          message: ''
        }
      }
      Object.assign(this.log , log);
      this.log.loading = true;
      this.log.queryId = row.queryId;
      service.getLog(row.queryId).then(
        res => {
          this.log.loading = false;
          let data = res.data;
          console.log(data);
          if(data){
            log.memoryPool = data.memoryPool;
            log.state = data.state;
            log.stateTitle = data.state === 'FAILED' ? (data.errorType || 'FAILED') : data.state;
            log.query = data.query.replace(/\/\*.*\*\/\s{0,}/, '');
            if(data['failureInfo']){
              log.isError = true;
              log.errorInfo.type = data['failureInfo'].errorCode.type;
              log.errorInfo.code = `${data['failureInfo'].errorCode.name}(${data['failureInfo'].errorCode.code})`;
              log.errorInfo.stack = data['failureInfo'].stack;
              log.errorInfo.errorType = data.failureInfo.type;
              log.errorInfo.message = data.failureInfo.message;
            }
            Object.assign(log.session , data.session || {});
            Object.assign(log.queryStats , data.queryStats || {});
          }
          Object.assign(this.log , log);
        }
      )
      // window.open(website.interactiveLogPrefix + 'ui/query.html?' + queryId);
    },
    isRunning(state){
      return !['FINISHED', 'FAILED', 'CANCELED'].includes(state);
    },
    sqlFormatter(sql){
      if(sql){
        return format(sql);
      }else{
        this.code = format(this.code);
      }
    },
    clearCode(){
      this.code = '';
    },
    getQuerySql(sql){
      return `/* ${this.userInfo.nick_name} */${sql}`
    },
    killQuery(queryId){
      this.$confirm('请确认操作', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        return service.killQuery({
          queryid: queryId,
          datasource: this.datasource.name
        })
      }).then(res => {
        this.queryHistory();
        this.$message({
          type: 'success',
          message: '操作成功!'
        });
      }).catch(() => {
      });
    },
    showCatalogs(){
      this.catalog.data = [];
      this.catalog.loading = true;
      this.presto('SHOW CATALOGS').then(
        res => {
          this.catalog.loading = false;
          this.catalog.data = res.data;
          if(this.catalog.data.length){
            this.catalog.model = this.catalog.data[0][res.useName];
            this.catalogChange();
          }
        }
      )
    },
    catalogChange(){
      this.schema.data = [];
      this.schema.loading = true;
      this.schema.model = '';
      this.table.model = '';
      this.tableDescribe.model = '';
      this.presto('SHOW SCHEMAS FROM ' + this.catalog.model).then(
        res => {
          this.schema.data = res.data;
          this.schema.loading = false;
          // if(this.schema.data.length){
          //   this.schema.model = this.schema.data[0][res.useName];
          //   this.schemaChange();
          // }
        }
      )
    },
    schemaChange(){
      this.table.data = [];
      this.table.loading = true;
      this.table.model = '';
      this.tableDescribe.model = '';
      this.presto(`SELECT table_name, table_type FROM ${this.catalog.model}.information_schema.tables WHERE table_schema='${this.schema.model}' ORDER BY table_name`).then(
        res => {
          this.table.loading = false;
          this.table.data = res.data;
          // if(this.table.data.length){
          //   this.table.model = this.table.data[0][res.useName];
          //   this.tableChange();
          // }
        }
      )
    },
    tableChange(){
      this.tableDescribe.data = [];
      this.tableDescribe.loading = true;
      this.tableDescribe.model = '';
      this.presto(`DESCRIBE ${this.catalog.model}.${this.schema.model}."${this.table.model}"`).then(
        res => {
          this.tableDescribe.loading = false;
          this.tableDescribe.data = res.data;
          if(this.tableDescribe.data.length){
            this.tableDescribe.model = this.tableDescribe.data[0][res.useName];
          }
        }
      )
    },
    presto(sql){
      let data = [] , name = '';
      return service.presto({
        datasource: this.datasource.name,
        query: this.getQuerySql(sql)
      }).then(
        res => {
          if(res.data.results){
            res.data.results.forEach(
              item => {
                if(item.length){
                  let newItem = {};
                  res.data.headers.forEach(
                    (name , index) => {
                      newItem[name] = item[index];
                    }
                  )
                  data.push(newItem);
                }
              }
            )
            name = res.data.headers[0] || ''
          }
          return {
            data: data,
            useName: name
          };
        }
      )
    },
    createSql(){
      if(this.shortcutSql.model === 1){
        let getColumn = () => {
          let column = '';
          if(this.expandColumn){
            let columnTemp = [];
            this.tableDescribe.data.forEach(
              item => {
                columnTemp.push(item[this.tableDescribe.headers[0].prop])
              }
            )
            column = columnTemp.join(',')
          }else{
            column = '*';
          }
          return column;
        }
        this.code = `SELECT ${getColumn()} FROM ${this.catalog.model}.${this.schema.model}."${this.table.model}" LIMIT 100`
      }else if(this.shortcutSql.model === 2){
        this.code = `SHOW CREATE TABLE ${this.catalog.model}.${this.schema.model}."${this.table.model}"`
      }else if(this.shortcutSql.model === 3){
        this.code = `DESCRIBE ${this.catalog.model}.${this.schema.model}."${this.table.model}"`
      }else if(this.shortcutSql.model === 2){
        this.code = `SHOW STATS FOR ${this.catalog.model}.${this.schema.model}."${this.table.model}"`
      }
    },
    excuteSQL(){
      if(this.code){
        this.activeName = 'result';

        this.result.headers = [];
        this.result.data = [];
        this.result.loading = true;
        this.result.count = 0;
        this.result.type = '';
        this.result.rawDataSize = '';
        this.result.createTime = '';
        this.result.elapsedTime = '';
        this.result.error = '';

        service.prestoAsync({
          datasource: this.datasource.name,
          query: this.code
        }).then(
          res => {
            // this.result.loading = false;
            this.excuteQueryId = res.data ? res.data.queryid : '';
            if(this.excuteQueryId){
              this.queryStatus();
            }
            // if(res.data){
            //   res.data.headers.forEach(
            //     (name , index) => {
            //       this.result.headers.push({
            //         label: name,
            //         prop: name
            //       })
            //     }
            //   )
            //   res.data.results.forEach(
            //     item => {
            //       let newItem = {};
            //       res.data.headers.forEach(
            //         (name , index) => {
            //           newItem[name] = item[index];
            //         }
            //       )
            //       this.result.data.push(newItem);
            //     }
            //   )
            // }
          }
        )
      }
    },
    queryStatus(){
      service.queryStatus({
        queryid: this.excuteQueryId,
        datasource: this.datasource.name
      }).then(
        res => {
          let state = (res.data.state || '').toLocaleLowerCase();
          if(!['queued' , 'finished' , 'failed'].includes(state)){
            this.queryStatus();
          }else{
            this.result.type = state;
            if(res.data.queryStats){
              this.result.createTime = res.data.queryStats.createTime;
              this.result.elapsedTime = res.data.queryStats.elapsedTime;
            }
            service.historyStatus({
              queryid: this.excuteQueryId,
              datasource: this.datasource.name,
              engine: this.datasource.config.engines[0] || 'presto'
            }).then(
              res => {
                if(res.data.status === 'ok'){
                  this.resultHistory();
                }
              }
            )
          }
        }
      )
    },

    tabsChange(){
      if(this.activeName === 'history'){
        this.queryHistory();
      }
    },
    resultHistory(){
      service.history({
        queryid: this.excuteQueryId,
        datasource: this.datasource.name,
        engine: this.datasource.config.engines[0] || 'presto'
      }).then(
        res => {
          if(res.data.results){
            res.data.headers.forEach(
              (name , index) => {
                this.result.headers.push({
                  label: name,
                  prop: name
                })
              }
            )
            res.data.results.forEach(
              item => {
                let newItem = {};
                res.data.headers.forEach(
                  (name , index) => {
                    newItem[name] = item[index];
                  }
                )
                this.result.data.push(newItem);
              }
            )
            this.result.count = this.result.data.length;
            this.result.rawDataSize = res.data.rawDataSize;
          }
          if(res.data.error){
            this.result.error = res.data.error;
          }
          this.result.loading = false;
        }
      )
    },
    queryHistory(){
      this.history.loading = true;
      this.history.data = [];
      service.query({
        datasource: this.datasource.name
      }).then(
        res => {
          this.history.loading = false;
          if(res.data){
            res.data.forEach(
              item => {
                let newItem = {
                  state: item.state,
                  user: item.session.user,
                  queryId: item.queryId,
                  query: item.query.replace(/\/\*.*\*\/\s{0,}/, ''),
                  elapsedTime: item.queryStats.elapsedTime,
                  createTime: item.queryStats.createTime,
                  existdb: item.existdb,
                  _popover: false,
                  _original: item 
                }
                this.history.data.push(newItem);
              }
            )
          }
        }
      )
    },
    showExcuteResult(row , existdb){
      if(existdb){
        this.result.headers = [];
        this.result.data = [];
        this.result.loading = true;
        this.result.count = 0;
        this.result.rawDataSize = '';
        this.result.error = '';
        this.result.type = row.state.toLocaleLowerCase();
        this.result.createTime = row._original.queryStats.createTime;
        this.result.elapsedTime = row._original.queryStats.elapsedTime;
        this.excuteQueryId = row.queryId;
        this.activeName = 'result';
        this.resultHistory();
      }
    }
  }
}
</script>
<style lang="scss">
.title-search-input{
  width: 60% !important;
  // .el-input__inner{
  //   height: 20px !important;
  //   line-height: 20px !important;
  // }
}
</style>